/********************************************************/
/*	Perlin Production Co. Ltd. August 2012		*/
/*	       Sprite mirror, version 1.0              	*/
/********************************************************/
/* MIRROR.C */

#include "stdio.h"

#define MAXWDT 64
char	buf[MAXWDT];
char	byte;

char	rotated(_byte)
char	_byte;
{
	byte = _byte;
#asm
	LDA	byte
	REPT	8
		rlc
	EndM
	STA	byte;
#endasm
	return byte;
}

RotSwap(_l,_r)
char	*_l;
char	*_r;
{
	char	tmp;

	if (_l == _r) *_l = rotated(*_r);
	else
	{
		tmp = rotated(*_r);
		*_r = rotated(*_l);
		*_l = tmp;
	}
}


main(argc,argv)
int	argc;
char	**argv;
{
	int		src,dst;
	char		srcfn[20],dstfn[20],tmpfn[20];
	char		*s,*defext;
	unsigned	count,width,wmid;
	char		*l,*r;

	defext = ".bin";

	if (argc < 3 || argc > 4)
	{
	 puts("Perlin Production Co. Ltd. 1994, 2012 (c)\n");
	 puts("MIRROR, ver.1.0. Mirrors sprite image in file.\n");
	 rev_vid();
	 puts("Usage:");
	 nrm_vid();
	 printf(" mirror width srcfile[%s] [dstfile[%s]]\n",defext,defext);
	 printf(" width of sprite is in bytes, [1-%d]",MAXWDT);
	 exit(0);
	}

	width	= ArgInt(argv, 1, 1, MAXWDT, "width");
	wmid	= width/2;

	strncpy(srcfn,argv[2],16);
	if ( index(srcfn,'.') == NULL ) strcat(srcfn,defext);

	strncpy(dstfn,argv[argc-1],16);
	if ( index(dstfn,'.') == NULL ) strcat(dstfn,defext);

	if ( (src=open(srcfn,FCB_READ)) == ERROR )
		problem("Can't open source file ",srcfn);

	strcpy(tmpfn,dstfn);
	if ( (s=index(tmpfn,':')) != NULL )
	{
		s++;
		*s=NULL;
	}
	else tmpfn[0]=NULL;
	strcat(tmpfn,"TEMPXX.$$$");
	if ( mktemp(tmpfn) == NULL )
	{
		errno=0;
		problem("Can't generate temporary file name",tmpfn);
	}

	if ( (dst=creat(tmpfn,FCB_WRITE)) == ERROR )
		problem("Can't create temporary file",tmpfn);


	for (count=0; read(src,buf,width) == width; ++count)
	{
		l = buf;
		r = buf[width-1];

		for ( ; l < r ; ) RotSwap(l++,r--);
		if (width & 0x1) buf[wmid]=rotated(buf[wmid]);

		if (write(dst,buf,width) !=width)
		{
		 rev_vid();
		 printf("\007Writing to temporary %s failed\n",tmpfn);
		 nrm_vid();
		 break;
		}
		if (!((count * width) % 128)) putchar('+');
	}
	printf("\n%u sprite line rotations performed,",count);
	printf("\n%u bytes written",count*width);

	if ( close(dst) == ERROR )
		problem(", can't close temporary",tmpfn);

	if ( !strcmp(dstfn,srcfn) )
	{
	    if ( unlink(srcfn) == ERROR )
	    {
		printf(", unable to delete source %s\n",srcfn);
		problem("Inverted bytes are in temporary",tmpfn);
	    }
	}
	unlink(dstfn);

	if ( rename(dstfn,tmpfn) == ERROR )
	{
		s = tmpfn;
		printf(", unable to rename temporary to %s\n",dstfn);
		problem("Inverted bytes are in temporary",tmpfn);
	}
	else s = dstfn;
	printf(" to %s\n",s);
}


problem(ts,fns)
char	*ts,*fns;
{
	if (errno)
	{
		printf("%s ",ts);
		perror(fns);
	}
	else	printf("%s %s",ts,fns);
	puts("\007");
	exit(1);
}
